/* * Copyright 2014-2016 Squarespace, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.squarespace.jersey2.guice; import javax.inject.Inject; import javax.inject.Provider; import javax.inject.Singleton; import javax.ws.rs.core.Application; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.Request; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.core.UriInfo; import javax.ws.rs.ext.Providers; import org.glassfish.hk2.api.ServiceLocator; import com.google.inject.Injector; import com.google.inject.servlet.RequestScoped; public class JerseyGuiceModule extends JerseyModule { private final ServiceLocator locator; public JerseyGuiceModule(String name) { this(JerseyGuiceUtils.newServiceLocator(name)); } public JerseyGuiceModule(ServiceLocator locator) { this.locator = locator; } @Override protected void configure() { Provider<Injector> injector = getProvider(Injector.class); bind(ServiceLocator.class).toProvider(new ServiceLocatorProvider(injector, locator)) .in(Singleton.class); Provider<ServiceLocator> provider = getProvider(ServiceLocator.class); bind(Application.class) .toProvider(new JerseyProvider<>(provider, Application.class)); bind(Providers.class) .toProvider(new JerseyProvider<>(provider, Providers.class)); bind(UriInfo.class) .toProvider(new JerseyProvider<>(provider, UriInfo.class)) .in(RequestScoped.class); bind(HttpHeaders.class) .toProvider(new JerseyProvider<>(provider, HttpHeaders.class)) .in(RequestScoped.class); bind(SecurityContext.class) .toProvider(new JerseyProvider<>(provider, SecurityContext.class)) .in(RequestScoped.class); bind(Request.class) .toProvider(new JerseyProvider<>(provider, Request.class)) .in(RequestScoped.class); } private static class JerseyProvider<T> implements Provider<T> { private Provider<ServiceLocator> provider; private final Class<T> type; public JerseyProvider(Provider<ServiceLocator> provider, Class<T> type) { this.provider = provider; this.type = type; } @Override public T get() { ServiceLocator locator = provider.get(); return locator.getService(type); } } private static class ServiceLocatorProvider implements Provider<ServiceLocator> { private final Provider<Injector> provider; private final ServiceLocator locator; @Inject public ServiceLocatorProvider(Provider<Injector> provider, ServiceLocator locator) { this.provider = provider; this.locator = locator; } @Override public ServiceLocator get() { Injector injector = provider.get(); JerseyGuiceUtils.link(locator, injector); return locator; } } }